package com.blb.aio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousServerSocketChannel;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;

/**
 * AIO模型服务器
 */
public class AIOServer {

    public void start() throws IOException, InterruptedException {
        //创建异步服务器通道
        AsynchronousServerSocketChannel channel = AsynchronousServerSocketChannel.open().bind(new InetSocketAddress(9999));
        //给通道设置接收客户端的回调
        channel.accept(null, new CompletionHandler<AsynchronousSocketChannel, Object>() {

            //完成连接
            @Override
            public void completed(AsynchronousSocketChannel socketChannel, Object attachment) {
                //获得客户端
                channel.accept(attachment,this);
                try {
                    System.out.println("客户端连接了:" + socketChannel.getRemoteAddress());
                    //从客户端读取数据
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    //设置读取数据的回调
                    socketChannel.read(buffer, buffer, new CompletionHandler<Integer, ByteBuffer>() {
                        @Override
                        public void completed(Integer result, ByteBuffer attachment) {
                            //将缓冲区由写模式转为读模型
                            buffer.flip();
                            //读取客户端消息
                            String msg = new String(buffer.array(),0,result);
                            System.out.println("收到客户端消息: " + msg);
                            //返回消息给客户端
                            socketChannel.write(ByteBuffer.wrap("Hello客户端我是服务器".getBytes()));
                        }

                        @Override
                        public void failed(Throwable exc, ByteBuffer attachment) {

                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            //失败连接
            @Override
            public void failed(Throwable exc, Object attachment) {

            }
        });
        //阻塞主线程，让回调能一直执行
        Thread.sleep(Integer.MAX_VALUE);
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        new AIOServer().start();
    }
}
